package com.chunlin.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

//定义一个类,让这个类里面属性的名字和类型都和json字符串匹配
//类似于Spring中的实体类
class User {
    //这里成员变量是否可以写作private呢?
    //可以的,但是必须要提供对应的getter和setter方法,不然的话,页面访问会是500说明后端内部有问题
    //本身，jackson会通过反射的方式，把User类里包含的public的属性都给获取到此时
    // 就可以根据反射这里得到的“属性名字”，去json解析出来的键值对中进行匹配
    // 如果匹配到了，就把value设置到刚才得到的属性中由于把username改成private了
    // 而jackson并不会直接针对private属性进行扫描(其实反射是可以做到的,但是作者不愿意破坏封装性)所以username就不认识了
    public String username;
    public String password;
}

/**
 * 此处约定客户端body按照json的格式来进行传输
 *
 * 其中格式为:
 * {
 *     "username" : "林小磊",
 *     "password" : "qcl22384981"
 * }
 */
@WebServlet("/json")
public class JsonServlet extends HelloServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        ObjectMapper objectMapper = new ObjectMapper();
        //第一个参数是一个流对象,,表示json从哪里来读取的数据
        //请求的body是通过getInputStream得到的流对象,进一步读取出来的
        //第二个参数，则是指定的类型.当前你这边得到的json字符串，需要转成一个啥样的Java对象，需要指定一下对象的类型
        //重点理解jackson的readValue工作过程
        // 先把json字符串解析成键值对放到Map中,
        // 再根据参数填入的类对象，通过反射api就可以知道，这个类里面有哪些属性,每个属性的名字和类型
        // 依次把这里的每个属性都取出来，通过属性名字查询上述的Map，把得到的值，赋值给这个类的属性
        User user = objectMapper.readValue(req.getInputStream(), User.class);
        //StringBuilder respBody = new StringBuilder();
        //respBody.append("username = " + user.username);
        //respBody.append("<br>");
        //respBody.append("password = " + user.password);
        //respBody.append("<br>");
        //resp.getWriter().write(respBody.toString());
        //jackson还提供了一个方法可以将Java对象,转换成json字符串
        String respJson = objectMapper.writeValueAsString(user);
        resp.getWriter().write(respJson);
    }
}
